<template>
  <div class="g-form-item" :class="{
      'success': messageStatus === 'success',
      'error': messageStatus === 'error'
    }">
    <div class="title_warp" v-if="title">
      <span class="title">{{title}}</span>
      <span class="label" :style="style" v-if="label">{{label}}</span>
    </div>
    <span class="label" :style="style" v-if="label && !title">{{label}}</span>
    <slot></slot>
    <transition name="error-message">
      <p class="error-message" :class="{'error-message-top':align === 'top'}" v-if="errorMessage">{{errorMessage}}</p>
    </transition>
  </div>
</template>

<script>
import AsyncValidator from 'async-validator'
export default {
  name: 'gFormItem',
  componentName: 'gFormItem',
  props: {
    label: {
      type: String
    },
    title: String,
    labelWidth: {
      type: Number,
      default: 70
    },
    prop: String
  },
  data() {
    return {
      errorMessage: '',
      messageStatus: '',
      verifyStatus: false
    }
  },
  computed: {
    style() {
      return {
        width: this.title ? 'auto' : this.labelWidth + 'px'
      }
    },
    // 获取验证信息
    rules() {
      return this.$parent.rules && this.$parent.rules[this.prop]
    },
    // 获取值
    fieldValue() {
      return this.$parent.form[this.prop]
    },
    // 获取头部对齐方式
    align() {
      return this.$parent.align
    }
  },
  methods: {
    // 监听验证
    verification() {
      if (this.prop && this.rules) {
        this.$parent.$emit('addForm', this)
        let trigger = this.getTrigger()
        this.$on(`g.form.${trigger}`, () => {
          this.validate()
        })
      }
    },
    // 获取input监听事件方式
    getTrigger() {
      if (this.rules instanceof Array) {
        let trigger = this.rules.filter(item => item.trigger)
        if (trigger.length) return trigger[0].trigger
      }
      if (this.rules instanceof Object) {
        let trigger = this.rules.trigger
        if (trigger) return trigger
      }
      return 'input'
    },
    // 处理验证规则
    handleRules() {
      let rules = this.rules
      if (rules instanceof Array) {
        if (rules[0].validator) {
          return rules
        }
        rules[0].required = true
      }
      if (rules instanceof Object) {
        rules.required = true
      }
      return rules
    },
    // 调用验证函数
    validate(callback) {
      return new Promise((resolve, reject) => {
        const rules = this.handleRules()
        const descriptor = {}
        descriptor[this.prop] = rules

        const validator = new AsyncValidator(descriptor)
        const model = {}

        model[this.prop] = this.fieldValue
        validator.validate(
          model,
          {
            firstFields: true
          },
          errors => {
            this.messageStatus = !errors ? 'success' : 'error'
            this.errorMessage = errors ? errors[0].message : ''
            this.verifyStatus = !errors
            resolve(this.verifyStatus)
          }
        )
      })
    }
  },
  created() {
    this.verification()
  },
  beforeDestroy() {
    this.$parent.$emit('removeForm', this)
  }
}
</script>

<style lang="less">
.g-form-item {
  position: relative;
}

.error-message {
  position: absolute;
  left: 90px;
  bottom: -10px;
  font-size: 12px;
  color: #ff5c5a;
}

.error-message-top {
  left: 0;
  bottom: 0;
}

.title {
  color: #2a84fc;
  font-size: 18px;
  margin-right: 15px;
}

.label {
  text-align: right;
  margin-right: 15px;
  display: inline-block;
  line-height: 48px;
  color: #808080;
  &.right {
    text-align: right;
  }
}

.success {
  input,
  textarea {
    border-color: #4285f4 !important;
  }
}

.error {
  input,
  textarea {
    border-color: #ff5c5a !important;
  }
}

.error-message-enter-active,
.error-message-leave-active {
  transition: all 0.5s;
}

.error-message-enter,
.error-message-leave-to {
  transform: translateY(-10%);
  opacity: 0;
}
</style>
